#include "../header/proc/proc_info.h"



cJSON* process_info(){
    DIR *dir =  NULL;
    struct dirent* entry;
    dir = opendir("/proc");
    if(dir == NULL){
        perror("open /proce error");
        return NULL;
    }
    cJSON *process_arr,*proc_item;
    int pid;
    char file_name[100];
    FILE *fp;
    char cmdline[4096] ;
    char usr_name[60];
    char link[4096];
    char mem_use[256];
    char proc_name[2048];
    process_arr = cJSON_CreateArray();

    while((entry = readdir(dir))){
        pid = atoi(entry->d_name);
        if(DT_DIR == entry->d_type && pid != 0){
            sprintf(file_name,"/proc/%s/cmdline",entry->d_name);
            fp = fopen(file_name,"r");
            if(fp!=NULL){
                proc_item = cJSON_CreateObject();
                fgets(cmdline,4096,fp);
                cJSON_AddStringToObject(proc_item, "command",cmdline);
                exe_real_path(entry->d_name,link);
                cJSON_AddStringToObject(proc_item, "path",link);
                get_pid_status_value(entry->d_name,"VmRSS",mem_use);
                cJSON_AddStringToObject(proc_item, "mem_use",mem_use);
                proc_usr_name(entry->d_name,usr_name);
                cJSON_AddStringToObject(proc_item, "usr_name",usr_name);
                get_pid_status_value(entry->d_name,"Name",proc_name);
                cJSON_AddStringToObject(proc_item, "proc_name",proc_name);
                cJSON_AddStringToObject(proc_item, "pid",entry->d_name);
                cJSON_AddItemToArray(process_arr,proc_item);
                fclose(fp);
            }else{
                strcat(file_name," open error");
                perror(file_name);
            }
        }
    }

    return process_arr;
}


void   exe_real_path(const char* pid,char* real_path){
    char exe_name[1024];
    sprintf(exe_name,"/proc/%s/exe",pid);
    if(access(exe_name,F_OK) != -1){
        readlink(exe_name,real_path,4096);
    }
}

void proc_usr_name(const char* pid,char* usr){
    sprintf(usr,"%s","N/A");
    char file_name[50];
    get_pid_status_value(pid,"Uid",file_name);

    uid_t my_uid;
    my_uid = atoi(file_name);
    struct passwd* my_info ;
    if(my_uid>=0){
        my_info = getpwuid( my_uid );
        sprintf(usr,"%s", my_info->pw_name );
    }

}

void get_pid_status_value(const char* pid,const char* name,char* file_name){
    FILE* fp;
    fp = get_status_file(pid);
    if(fp != NULL){
        char status_content[256];
        char tag_name[20];
        while(fgets(status_content,256,fp)!=NULL){
            if(strstr(status_content,name)!=NULL){
                sscanf(status_content,"%s %s",tag_name,file_name);
            }
         }
         fclose(fp);
    }
}

FILE* get_status_file(const char* pid){
    char status_path[256];
    FILE* fp;
    sprintf(status_path,"/proc/%s/status",pid);
    fp = fopen(status_path,"r");
    if(fp == NULL){
        char error_msg[50];
        sprintf(error_msg,"/proc/%s/status open error",pid);
        perror(error_msg);
        return NULL;
    }
    return fp;


}
